using System;
using System.Diagnostics;
using System.Net;
using System.Windows.Forms;
using System.IO;
using Aga.Controls.Tree;
using DC;
using DC.Http;
using MediaDC.Native;

namespace MediaDC.Forms
{
    public partial class MainForm : Form
    {
        private readonly MdiWindowsManager _windowsManager;
        private readonly WebServer _webServer;
        private readonly string _tempFolder;
        private readonly TreeModel _statusModel;
        private ConsoleTraceListener _consoleTraceListener;

        public MainForm()
        {
            InitializeComponent();

			_windowsManager = new MdiWindowsManager(this);
            _windowsManager.Dock = DockStyle.Bottom;

            _statusModel = new TreeModel();
            progressView.Model = _statusModel;

            TaskMonitor.OnTaskStarted += TaskMonitor_OnTaskStarted;

            _tempFolder = Path.Combine(Config.Instance.TempFolderPath, "MDC");
            Directory.CreateDirectory(_tempFolder);

            Controls.Add(_windowsManager);

            Closed += delegate { Config.Instance.Save(); };

            HubConnectionManager.Initialize(Config.Instance.IP, _tempFolder);

            foreach (HubRegistration registration in Config.Instance.RegistredHubUrls)
            {
                HubClient c = HubConnectionManager.CreateClient(string.IsNullOrEmpty(registration.NickName) ? Config.Instance.NickName : registration.NickName);

                c.OnFileListRecived += OnFileListRecived;
                c.OnFileRecived += OnFileRecived;
                HubInfoForm hubInfoForm = new HubInfoForm(registration, c);
                _windowsManager.AddForm(hubInfoForm);
                hubInfoForm.Show();
            }

        	try
        	{
				_webServer = new WebServer();
				_webServer.Start(Config.Instance.WebServerPort);
        	}
        	catch (Exception ex)
        	{
        		MessageBox.Show(
        			"Unable to start web server. Probably selected port is busy. Please choose another port and restart apllication");
				Trace.Write(ex);
        	}
			
			CheckForUpdates();
        }

    	private void CheckForUpdates()
    	{
#if !DEBUG
			WebClient wc = new WebClient();
			try
			{
				string result = wc.DownloadString("http://mdc.505.ru/updatecheck.php?version=" + Config.Instance.Version);
				Version newVersion = new Version(result);
				Version knownVersion = new Version(Config.Instance.LastNotifiedVersion);
				if (newVersion > knownVersion)
				{
					MessageBox.Show(this,
				string.Format("New version {0} is available.{1}Please visit http://mdc.505.ru for details.", result, Environment.NewLine),
				"Update info");

								Config.Instance.LastNotifiedVersion = newVersion.ToString();
				}
			}
			catch
			{
			}
#endif
    	}


    	void TaskMonitor_OnTaskStarted(object sender, TaskEventArgs e)
        {
            lock (_statusModel)
            {
                _statusModel.Nodes.Add(new StatusNode(e.Task));
            }
        }

        private static void OnFileRecived(object sender, FileRecivedEventArgs e)
        {
            PreviewManager.ProcessRecivedFile(e.FileName);
        }

        private void OnFileListRecived(object sender, FileListRecivedEventArgs e)
        {
            if (InvokeRequired)
            {
                Invoke(new EventHandler<FileListRecivedEventArgs>(OnFileListRecived), sender, e);
            }
            else
            {
                FileListForm fileList = new FileListForm(((HubClient)sender).ID, e.NickName, e.Listing);
                _windowsManager.AddForm(fileList);
                fileList.Show();
            }
        }

        private void optionsButton_Click(object sender, EventArgs e)
        {
            new OptionsForm().ShowDialog();
        }

        private void searchButton_Click(object sender, EventArgs e)
        {
            SearchForm f = new SearchForm();
            _windowsManager.AddForm(f);
            f.Show();
        }

        private void aboutMenuItem_Click(object sender, EventArgs e)
        {
            using (Form about = new AboutBox())
            {
                about.ShowDialog();
            }
        }

        private void ExitToolsStripMenuItem_Click(object sender, EventArgs e)
        {
            Close();
        }

        private void ToolBarToolStripMenuItem_Click(object sender, EventArgs e)
        {
            toolStrip.Visible = toolBarToolStripMenuItem.Checked;
        }

        private void StatusBarToolStripMenuItem_Click(object sender, EventArgs e)
        {
            statusStrip.Visible = statusBarToolStripMenuItem.Checked;
        }

        private void consoleToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (consoleToolStripMenuItem.Checked)
            {
                NativeConsole.CreateConsole();
                _consoleTraceListener = new ConsoleTraceListener();
                Trace.Listeners.Add(_consoleTraceListener);
                Debug.Listeners.Add(_consoleTraceListener);
            }
            else
            {
                Trace.Listeners.Remove(_consoleTraceListener);
                Debug.Listeners.Remove(_consoleTraceListener);
                _consoleTraceListener.Flush();
                NativeConsole.ReleaseConsole();
            }
                
        }

        #region "Mdi windows processing"

        private void CascadeToolStripMenuItem_Click(object sender, EventArgs e)
        {
            LayoutMdi(MdiLayout.Cascade);
        }

        private void TileVerticalToolStripMenuItem_Click(object sender, EventArgs e)
        {
            LayoutMdi(MdiLayout.TileVertical);
        }

        private void TileHorizontalToolStripMenuItem_Click(object sender, EventArgs e)
        {
            LayoutMdi(MdiLayout.TileHorizontal);
        }

        private void ArrangeIconsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            LayoutMdi(MdiLayout.ArrangeIcons);
        }

        private void CloseAllToolStripMenuItem_Click(object sender, EventArgs e)
        {
            foreach (Form childForm in MdiChildren)
            {
                childForm.Close();
            }
        }

        #endregion

        private void MainForm_FormClosed(object sender, FormClosedEventArgs e)
        {
            try
            {
                Directory.Delete(_tempFolder, true);
            }
            catch
            {
                Trace.WriteLine(string.Format("Unable to delete temp folder: {0}", _tempFolder));
            }

        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            RefreshNodes();
        }

        private void RefreshNodes()
        {
            foreach (Node n in _statusModel.Nodes)
            {
                StatusNode node = (StatusNode)n;
                node.Refresh();
            }

            lock (_statusModel)
            {
                for (int i = _statusModel.Nodes.Count - 1; i >= 0; i--)
                {
                    StatusNode node = (StatusNode)_statusModel.Nodes[i];
                    if (node.Status == TaskStatus.Canceled ||
                            (node.Status != TaskStatus.Downloading && node.LastStatusUpdateTime.AddSeconds(15) < DateTime.Now)
                        )
                        _statusModel.Nodes.RemoveAt(i);
                }
            }
            progressView.Refresh();
        }
    }
}
